﻿using System.Collections.Generic;

namespace Magellan.Routing
{
    public class ParsedRoute
    {
        private readonly Segment[] _segments;

        public ParsedRoute(params Segment[] segments)
        {
            _segments = segments;
        }

        public Segment[] Segments
        {
            get { return _segments; }
        }

        public RouteMatch MatchPathToRoute(IRoute route, string request)
        {
            var values = new RouteValueDictionary();
            var iterator = new PathIterator(request);

            foreach (var segment in Segments)
            {
                var match = segment.MatchPath(route, iterator);
                if (match.Success)
                {
                    values.AddRange(match.Values);
                }
                else
                {
                    return RouteMatch.Failure(route, match.FailReason);
                }
            }

            return iterator.IsAtEnd
                ? RouteMatch.Successful(route, values)
                : RouteMatch.Failure(route, "Route was initially matched, but the request contains additional unexpected segments");
        }

        public PathMatch MatchRouteToPath(IRoute route, RouteValueDictionary values)
        {
            var valueBag = new RouteValueBag(values);
            var segmentValues = new List<object>();
            
            foreach (var segment in Segments)
            {
                var match = segment.MatchValues(route, valueBag);
                if (match.Success)
                {
                    segmentValues.Add(match.SegmentValue);
                }
                else
                {
                    return PathMatch.Failure(route, match.FailReason);
                }
            }

            return valueBag.IsEmpty
                ? PathMatch.Successful(route, segmentValues)
                : PathMatch.Failure(route, "Route was partially matched, but additional values in the value dictionary could not be accounted for.");
        }
    }
}